package com.csw.android.androidtest.net.socket.tcp;

import com.csw.android.androidtest.net.socket.base.BaseSocket;
import com.csw.android.androidtest.net.socket.base.SocketListener;

import java.io.InputStream;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketAddress;

public class TCPServerSocket extends BaseSocket {
    private Socket socket;

    public TCPServerSocket(SocketListener socketListener) {
        super(socketListener);
    }

    @Override
    protected void closeResource() {
        super.closeResource();
        if (socket != null) {
            try {
                socket.close();
                socket = null;
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    @Override
    protected void execConnect() throws Exception {
        ServerSocket serverSocket = new ServerSocket();
        serverSocket.setSoTimeout(0);//超时设置,服务端等待多久就返回超时，不再等待客户端连接，0表示无限等待
        InetSocketAddress inetSocketAddress;
        if (ip != null) {
            inetSocketAddress = new InetSocketAddress(ip, port);
        } else {
            inetSocketAddress = new InetSocketAddress(port);
        }
        //为socket绑定地址和端口
        serverSocket.bind(inetSocketAddress);
        ip = serverSocket.getInetAddress().getHostAddress();
        port = serverSocket.getLocalPort();
        socketListener.onPrepared(ip, port);
        //等待客户端连接,等待过程阻塞
        socket = serverSocket.accept();
        SocketAddress socketAddress = socket.getRemoteSocketAddress();
        if (socketAddress instanceof InetSocketAddress) {
            InetSocketAddress inetSocketAddress1 = (InetSocketAddress) socketAddress;
            setDestInfo(inetSocketAddress1.getAddress().getHostAddress(), inetSocketAddress1.getPort());
        }
    }

    @Override
    protected void execRead() throws Exception {
        InputStream inputStream = null;
        try {
            //socket基于连接，从头读到尾，读不到就阻塞
            inputStream = socket.getInputStream();
            while (getState() == 2) {
                TCPMessage tcpMessage = TCPMessage.readFromStream(inputStream);
                socketListener.onReceiveMessage(tcpMessage.getData());
            }
            close();
        } catch (Exception e) {
            throw e;
        } finally {
            if (inputStream != null) {
                inputStream.close();
            }
        }
    }

    @Override
    protected void execWrite(byte[] data) throws Exception {
        new TCPMessage(data).write(socket.getOutputStream());
    }
}
